import { pickedFaceData, pickedLineData } from '@amcax/base';
import i18n from '@app-cad/common/utils/i18next';
import { NMTopoBaseCommand } from '@app-cad/environments/nextmesh/types/command';

import { MergeMode, TopoDialogProps } from '../type';
import { useEffect, useMemo, useState } from 'react';

import { documentV2 } from '@app-nextmesh/domain';

import { useCommand } from '@app-base/common/hooks/useCommand';

import { UiSchema } from '@rjsf/utils';
import { PickInputRJSFFormat } from '@app-base/common/components/command-form/constants';

import { PickableCommandForm } from '@app-base/common/components/command-form/pickable';

import { RadioButtonFields } from '../cmd-common/radioButtonFields';

type FormData = {
  firstEdge?: pickedLineData;
  secondEdge?: pickedLineData;
  faces?: pickedFaceData[];
  mode: string;
};
function TopoMergeDialog({ title, onClose }: TopoDialogProps) {
  const [formData, setFormData] = useState<FormData>({
    firstEdge: null,
    secondEdge: null,
    faces: [],
    mode: MergeMode.TwoEdges,
  });
  useCommand('cmdTopoModify', {
    onClose,
  });
  useEffect(() => {
    setFormData({
      firstEdge: null,
      secondEdge: null,
      faces: [],
      mode: formData.mode,
    });
  }, [formData.mode]);
  const schema = useMemo(() => {
    const modeSchema = {
      mode: {
        type: 'string',
        enum: [MergeMode.TwoEdges, MergeMode.AutoOnFaces],
        default: MergeMode.TwoEdges,
      },
    };
    if (formData.mode === MergeMode.TwoEdges) {
      return {
        properties: {
          mode: modeSchema,
          firstEdge: {
            type: 'string',
            format: PickInputRJSFFormat.PickCurve,
            uniqueItems: true,
          },
          secondEdge: {
            type: 'string',
            format: PickInputRJSFFormat.PickCurve,
            uniqueItems: true,
          },
        },
      };
    }
    if (formData.mode === MergeMode.AutoOnFaces) {
      return {
        properties: {
          mode: modeSchema,
          faces: {
            type: 'array',
            items: {
              type: 'string',
              enum: [],
            },
            format: PickInputRJSFFormat.MultiPickFace,
            uniqueItems: true,
          },
        },
      };
    }
    return schema;
  }, [formData.mode]);

  const uiSchema: UiSchema = {
    mode: {
      'ui:field': RadioButtonFields,
      'ui:options': {
        options: [
          {
            value: MergeMode.TwoEdges,
            label: '合并边',
          },
          {
            value: MergeMode.AutoOnFaces,
            label: '合并相近边',
          },
        ],
      },
    },
    firstEdge: {
      'ui:placeholder': '请选择第一条边',
      'ui:autofocus': true,
    },
    secondEdge: {
      'ui:placeholder': '请选择第二条边',
    },
    faces: {
      'ui:placeholder': '请选择多个面',
      'ui:autofocus': true,
    },
  };
  const isValid = (): boolean => {
    if (!formData) {
      return false;
    }
    switch (formData.mode) {
      case MergeMode.TwoEdges:
        return !!formData.firstEdge && !!formData.secondEdge;
      case MergeMode.AutoOnFaces:
        return formData.faces.length > 0;
      default:
        return false;
    }
  };
  const handleSubmit = async () => {
    const { firstEdge, secondEdge, faces, mode } = formData;
    let params = null;
    if (formData.mode === MergeMode.TwoEdges) {
      params = {
        source: [firstEdge.edgeId],
        target: [secondEdge.edgeId],
        mode,
      };
    } else {
      params = {
        source: faces.map((item) => {
          return item.meshId;
        }),
        mode,
      };
    }
    await documentV2.mergeEntity(params);
    onClose();
  };
  return (
    <PickableCommandForm
      schema={schema}
      title={title}
      onClose={onClose}
      extraUiSchema={uiSchema}
      formData={formData}
      isFormDataValid={isValid()}
      onChange={(data) => {
        setFormData(data);
      }}
      onSubmit={handleSubmit}></PickableCommandForm>
  );
}
export const cmdTopoMerge: NMTopoBaseCommand = {
  id: 'cmdTopoMerge',
  icon: 'commands/curved/point',
  label: 'command.topo.merge',
  create: (label: string, onClose: () => void, props) => (
    <TopoMergeDialog
      title={i18n.t(label)}
      onClose={onClose}
      props={props}
      placement='topLeft'
    />
  ),
};
